#include "SudokuCell.h"

SudokuCell::SudokuCell(int _sizeBox, int _col, int _row) :
        value(0), prior(Empty), sizeBox(_sizeBox), col(_col), row(_row),
index(_row*_sizeBox*_sizeBox+_col), towerIndex(_col/(_sizeBox)),
floorIndex(_row/(_sizeBox)),
boxIndex(floorIndex*_sizeBox+towerIndex),
colInBox(_col%_sizeBox), rowInBox(_row%_sizeBox), indexInBox(rowInBox*_sizeBox+colInBox),
possiblArr(_sizeBox*_sizeBox, true)
{
    //TODO default values
}

SudokuCell::SudokuCell(int _sizeBox, int _value, CellFillerTypes _prior, int _col, int _row):
        value(_value), prior(_prior), sizeBox(_sizeBox), col(_col), row(_row),
        index(_row*_sizeBox*_sizeBox+_col), towerIndex(_col/(_sizeBox)),
        floorIndex(_row/(_sizeBox)),
        boxIndex(floorIndex*_sizeBox+towerIndex),
colInBox(_col%_sizeBox), rowInBox(_row%_sizeBox), indexInBox(rowInBox*_sizeBox+colInBox)
{
    //TODO possiblArr stays empty
}

SudokuCell::SudokuCell(const SudokuCell& cell)
{
    qDebug() << "SudokuCell copy constructor";
    copyCell(cell);
}

SudokuCell::~SudokuCell()
{
}

SudokuCell& SudokuCell::operator=(const SudokuCell& cell)
{
    qDebug() << "SudokuCell::operator=";
    if (&cell == this)
        return *this;

    copyCell(cell);

    return *this;
}

void SudokuCell::copyCell(const SudokuCell& cell)
{
    value = cell.value;
    prior = cell.prior;
    sizeBox = cell.sizeBox;
    col = cell.col;
    row = cell.row;
    index = cell.index;
    towerIndex = cell.towerIndex;
    floorIndex = cell.floorIndex;
    boxIndex = cell.boxIndex;
    colInBox = cell.colInBox;
    rowInBox = cell.rowInBox;
    indexInBox = cell.indexInBox;
    possiblArr = cell.possiblArr;//TODO copy?
}

void SudokuCell::setValue(int _value, CellFillerTypes _prior)
{
    value = _value;
    prior = _prior;
}

void SudokuCell::setPossibl(int index, bool possibl, CellFillerTypes method)
{
    Q_ASSERT(isEmpty());
    possiblArr.setCandidate(index, possibl, method);
}

void SudokuCell::setAllPossibl()
{
    possiblArr.setAllPossible();
}

void SudokuCell::resetEliminated()
{
    possiblArr.resetEliminated();
}

void SudokuCell::clear()
{
    value = 0;
    prior = Empty;
    possiblArr.setAllPossible();
}

QDebug operator<<(QDebug dbg, const SudokuCell& cell)
{
    dbg.nospace() << "[" << cell.value << "(";//"[" << cell.value << "(" << cell.prior << "){";
    for(int i=0;i<cell.possiblArr.size();++i)
        if(cell.possiblArr.at(i))
            dbg.nospace() << i+1;// << ",";
    dbg.nospace() << ")]";
    return dbg.maybeSpace();
}

bool SudokuCell::hasMoreCandidates(const SudokuCell* cell1, const SudokuCell* cell2)
{
    return !hasLessCandidates(cell1, cell2);
}

bool SudokuCell::hasLessCandidates(const SudokuCell* cell1, const SudokuCell* cell2)
{
    if(cell1->isEmpty() && cell2->isEmpty())//both empty
        return (cell1->countPossible() < cell2->countPossible());
    if(!cell1->isEmpty() && !cell2->isEmpty())//both filled
       return (cell1->getValue() < cell2->getValue());
    return cell1->isEmpty();
}
//TODO test that method
bool SudokuCell::hasSameCandidatesOrLess(const SudokuCell* otherCell) const
{
    for(int i=0;i<possiblArr.size();++i)//TODO size not available here, use possiblArr.size()
        if( !otherCell->getPossibl(i) && this->getPossibl(i))
            return false;

    return true;
}
